//////////////////////////////////////////////////////////////////////////////////
//	Copyright 2011 by Yosef Grabivker, ryuho@homenetworksoft.com
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
//////////////////////////////////////////////////////////////////////////////////

#include <wx/wx.h>
#include <wx/gbsizer.h>

#include <ctype.h>
#include <algorithm>
#include <sstream>
#include "rcmdapp.h"
#include "mainwnd.h"
#include "isptab.h"
#include "logicmanager.h"
#include "traficgraph.h"
#include "traficcolorselector.h"
#include "levelgraph.h"

using namespace std;

#define SEARCH_NAME		wxT("Web Search")
#define SOCIAL_NAME		wxT("Social Networks")
#define COMP_NAME		wxT("All")

enum cIDS
{
	ID_PING_TIME_SELECTOR=3201,
};

BEGIN_EVENT_TABLE(CISPTab, wxPanel)
	EVT_TEXT(ID_PING_TIME_SELECTOR, 	CISPTab::OnTimeRangeChanged)
END_EVENT_TABLE()

CISPTab::CISPTab(class wxWindow* pParent):wxPanel(pParent)
{
	int nFlags=wxLEFT|wxRIGHT|wxDOWN|wxEXPAND|wxALIGN_CENTRE_VERTICAL;
	int nBorder=8;
	wxString label;

	wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);

	wxBoxSizer* sizerGraph = new wxBoxSizer(wxHORIZONTAL);

	////////////////////////////////////////////////////////////////////
	//m_pLinePing
	label = _("Response time Graph");
	wxStaticBoxSizer* pBox1 = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY,label), wxVERTICAL);

	//Add Time selector
	m_pLinePing = new CLevelGraph(this, CLevelGraph::cNormalGraphMode, CLevelGraph::cGraphLabelRight, wxID_ANY);

	wxBoxSizer* pCRCTitleBox = GraphicHeader(label, ID_PING_TIME_SELECTOR, m_pLinePing );
	pBox1->Add(pCRCTitleBox, 0, wxALIGN_RIGHT, 0);
	
	pBox1->Add( m_pLinePing, 1, nFlags, nBorder );
	sizerGraph->Add( pBox1, 1, nFlags, nBorder );

	m_pLinePing->SetColor(SEARCH_NAME, *wxRED);
	m_pLinePing->SetColor(SOCIAL_NAME, *wxBLUE);
	m_pLinePing->SetMesureName(wxT("ms"));

	ZONERANGE zone;
	ZONELIST list;

	//Bad
	zone.color = BAD_COLOR;
	zone.nFrom = 400;
	zone.nTo   = 100000;
	list.push_back(zone);

	//Fair
	zone.color = FAIR_COLOR;
	zone.nFrom = 200;
	zone.nTo   = 400;
	list.push_back(zone);

	//Good
	zone.color = GOOD_COLOR;
	zone.nFrom = 100;
	zone.nTo   = 200;
	list.push_back(zone);

	//Excelent
	zone.color = EXCELENT_COLOR;
	zone.nFrom = 0;
	zone.nTo   = 100;
	list.push_back(zone);

	m_pLinePing->SetZones(list);

	sizer->Add(sizerGraph, 1, wxALL|wxEXPAND, 5);
	
	SetSizer(sizer);
}

wxBoxSizer* CISPTab::GraphicHeader(const wxString& strTitle, int id, CLevelGraph* pGraph )
{
	wxBoxSizer* pRightSizer = new wxBoxSizer(wxHORIZONTAL);
	int nFlagsLocal=wxLEFT|wxUP|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT;
	int nBorder=5;

	pRightSizer->Add(new wxStaticText(this, wxID_ANY, _("Time period:")), 0, nFlagsLocal, nBorder);

	wxComboBox* pComboBox = new wxComboBox(this, id, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_DROPDOWN|wxCB_READONLY );

	AddTimeValues(pComboBox, pGraph);

	pRightSizer->Add(pComboBox, 0, nFlagsLocal, 0);

	return pRightSizer;
}

CISPTab::~CISPTab()
{
}

void CISPTab::AddTimeValues(wxComboBox* pComboBox, CLevelGraph* pGraph)
{
	wxString strM(_("minute"));
	wxString strMs(_("minutes"));
	wxString strH(_("hour"));
	wxString strHs(_("hours"));

	pComboBox->Append( wxString(wxT("1 "))+strM,	(void*)60		 );
	//pComboBox->Append( wxString(wxT("2 "))+strMs,	(void*)(2*60)     );
	pComboBox->Append( wxString(wxT("5 "))+strMs,	(void*)(5*60)     );
	pComboBox->Append( wxString(wxT("10 "))+strMs,	(void*)(10*60)    );
	pComboBox->Append( wxString(wxT("30 "))+strMs,	(void*)(30*60)    );
	pComboBox->Append( wxString(wxT("1 "))+strH,	(void*)(1*60*60)  );
	pComboBox->Append( wxString(wxT("12 "))+strHs,	(void*)(12*60*60) );
	pComboBox->Append( wxString(wxT("24 "))+strHs,	(void*)(24*60*60) );

	pComboBox->SetSelection(1);
	pGraph->SetTimePeriod(5*60);
}

void CISPTab::OnTimeRangeChanged(wxCommandEvent& ev)
{
	wxComboBox* pComboBox = (wxComboBox* )ev.GetEventObject();

	int nSel = pComboBox->GetCurrentSelection();

	if ( wxNOT_FOUND!=nSel )
	{
		void* p = pComboBox->GetClientData(nSel);
		int	timeRange = (int)p;

		m_pLinePing->SetTimePeriod(timeRange);
	}
}


//IGUIBind
void CISPTab::OnResponse(const COMMANDRESPONSE& resp)
{
	try
	{
		ParseResponse( resp );

		ProcessResponse();
	}
	catch (...)
	{
	}
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//IGUISupport
wxString CISPTab::Save()
{
	wxString str;



	return str;
}


void CISPTab::ProcessResponse()
{
	time_t tEvent = time(NULL);

	//m_pLineErr->SetData( UCRC_ERR, nCRCUp,  tEvent );
	//m_pLineErr->SetData( DCRC_ERR, nCRCDown,  tEvent );
}

void CISPTab::Reset()
{
	time_t tEvent = time(NULL);

	m_pLinePing->SetData( SEARCH_NAME, 0,  tEvent );
	m_pLinePing->SetData( SOCIAL_NAME, 0,  tEvent );
}

/*
PING google.com (74.125.79.104): 56 data bytes
64 bytes from 74.125.79.104: icmp_seq=0 ttl=52 time=100.0 ms
64 bytes from 74.125.79.104: icmp_seq=1 ttl=52 time=100.0 ms

--- google.com ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 100.0/100.0/100.0 ms
*/

void CISPTab::ParseResponse(const COMMANDRESPONSE& resp)
{
	time_t tEvent = time(NULL);

	stringstream sIn( resp.strData.c_str() );

	wxString strSite;
	
	char buf[512];
	char tmp[512];

	int nFnd;

	float fMin, fAvrg, fMax;
	long lTransm, lRecv;

	enum cStages { cStageHeader=1, cStagePCount=1<<1, cStageRTT=1<<2, cStageDone =  cStageHeader|cStagePCount|cStageRTT};

	long lStatus = 0;

	while ( !sIn.getline(buf, sizeof(buf)).eof() )
	{
		nFnd = sscanf(buf, "PING %s", tmp);

		if ( 1==nFnd )
		{
			strSite = wxString::FromAscii(tmp);

			if (!strSite.empty())
			{
				lStatus|=cStageHeader;
				continue;
			}
		}

		nFnd = sscanf(buf, "%d packets transmitted, %d packets received", &lTransm, &lRecv );

		if (2==nFnd)
		{
			lStatus|=cStagePCount;
			continue;
		}


		nFnd = sscanf(buf, "round-trip min/avg/max = %f/%f/%f", &fMin, &fAvrg, &fMax);

		if (3==nFnd)
		{
			lStatus|=cStageRTT;
		}

		if ( (lStatus&cStageDone) == cStageDone )
		{
			m_pLinePing->SetData( strSite, fAvrg,  tEvent );
			lStatus = 0;
		}
	}
}
